package com.sync.tanm;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;

import com.admin.param.contract.IOrganizeRequestParam;
import com.admin.vo.CompanyInfoVO;
import com.common.util.FlattenTree;
import com.common.util.ListConvertMap;
import com.competition.param.impl.OrganizeRequestParam;
import com.competition.param.impl.VisitRequestParam;
import com.competition.web.admin.config.HttpRequest;
import com.competition.web.admin.util.WithdrawalOfSurplus;
import com.competition.web.constant.RedisConstant;
import com.unify.type.Data;
import com.unify.type.Department;
import com.unify.type.DepartmentFlatten;
import com.unify.type.ExploringHorsesResponse;
import com.unify.type.SearchColumn;
import com.unify.type.SearchColumn.Option;
import com.unify.type.StaffByExploringHorses;

/**
 * to
 */
public class SyncTanma {

	/**
	 * 放弃人姓名：field 136107
	 */
	private static String NAME_OF_ABANDONED_PERSON = "136107";

	static Logger LOGGER = LoggerFactory.getLogger(SyncTanma.class);

	private RedisTemplate<String, ?> redisTemplate;
	private HttpRequest httpRequest;

	private static class SyncTanmaHolder {
		static SyncTanma syncTanma;
	}

	private SyncTanma(HttpRequest httpRequest, RedisTemplate<String, ?> redisTemplate) {

		this.httpRequest = httpRequest;

		this.redisTemplate = redisTemplate;
	}

	public static SyncTanma getInstance() {
		return SyncTanmaHolder.syncTanma;
	}

	public static void init(HttpRequest httpRequest, RedisTemplate<String, ?> redisTemplate) {

		if (null != SyncTanmaHolder.syncTanma) {
			return;
		}

		SyncTanmaHolder.syncTanma = new SyncTanma(httpRequest, redisTemplate);
	}

	public HttpRequest getHttpRequest() {
		return httpRequest;
	}

	public void setHttpRequest(HttpRequest httpRequest) {
		this.httpRequest = httpRequest;
	}

	public void loadTanma() {
		// 请求探马 获取 二道的员工所拥有的企业

		List<DepartmentFlatten> organizeData = this.getOrganizeData();

		HashOperations<String, String, Object> opsForHash = redisTemplate.opsForHash();

		Long size = opsForHash.size(RedisConstant.COMPANY_INFO);

		if (0 != size) {
			return;
		}

		this.httpRequest.getThreadPoolTaskExecutor().execute(() -> {
			pushCompanyInfo(organizeData, opsForHash);
		});

	}

	/**
	 * 将企业信息写入缓存
	 * 
	 * @param organizeData
	 * @param opsForHash
	 */
	public void pushCompanyInfo(List<DepartmentFlatten> organizeData,
			HashOperations<String, String, Object> opsForHash) {

		try {

			List<Long> staffIds = new ArrayList<Long>();

			List<StaffByExploringHorses> users;

			for (DepartmentFlatten departmentFlatten : organizeData) {

				users = departmentFlatten.getUsers();

				for (StaffByExploringHorses staffByExploringHorses : users) {

					staffIds.add(staffByExploringHorses.getId());
				}
			}

			int page = 1;

			Long[] userIds = staffIds.stream().toArray(Long[]::new);

			Data<Map<?, ?>> company = getCompany(userIds, page, opsForHash);

			if (null == company) {
				return;
			}

			int totalCount = company.getTotalCount();

			int pageSize = company.getPageSize();

			long ofSurplus = WithdrawalOfSurplus.ofSurplus(totalCount, pageSize);

			long currentTimeMillis;

			for (int i = 2; i < ofSurplus; i++) {

				currentTimeMillis = System.currentTimeMillis();

				getCompany(userIds, i, opsForHash);

				LOGGER.debug("次数：{}， 秒数：{}", i, System.currentTimeMillis() - currentTimeMillis);
			}

			opsForHash.put(RedisConstant.TANMA_COMPLATE_KEY, RedisConstant.TANMA_COMPLATE_KEY, "1");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Data<Map<?, ?>> getCompany(Long[] userIds, int page, HashOperations<String, String, Object> opsForHash) {

		VisitRequestParam visitRequestParam = new VisitRequestParam();

		visitRequestParam.setPageSize(100);
		visitRequestParam.setSalesIdList(userIds);
		visitRequestParam.setRole("1");

		visitRequestParam.setPageNo(page);

		ParameterizedTypeReference<ExploringHorsesResponse<Data<Map<?, ?>>>> parameterizedTypeReference = new ParameterizedTypeReference<ExploringHorsesResponse<Data<Map<?, ?>>>>() {
		};

		// 获取电邀负责的客户
		ExploringHorsesResponse<Data<Map<?, ?>>> exploringHorsesResponse = this.httpRequest
				.postExploringHorsesSync(visitRequestParam, parameterizedTypeReference);

		if (0 != exploringHorsesResponse.getCode()) {
			return null;
		}

		Data<Map<?, ?>> data = exploringHorsesResponse.getData();

		if (null == data) {
			return null;
		}

		List<Map<?, ?>> list = data.getData();

		CompanyInfoVO vo;

		String city;

		List<Map<?, ?>> fullAddress;

		Map<?, ?> address;

		SearchColumn searchColumn = getSearchColumn();

		Map<Long, Option> mapFromCity = ListConvertMap.listToMap(searchColumn.getOptions(), Option::getId);

		Object addressReal;
		Long id;

		for (Map<?, ?> map : list) {

			id = (Long) map.get("id");
			vo = new CompanyInfoVO();

			vo.setId(id);

			String cropName = (String) map.get("corpName");

			try {
				vo.setCompanyName(cropName);

				vo.setCustomerId((Long) map.get("customerId"));

				city = (String) map.get("99806");

				if (null == city) {
					Integer cityId = (Integer) map.get("95560");

					if (null == cityId) {
						// id++;
						continue;
					}

					city = mapFromCity.get(cityId.longValue()).getName();
				}

				vo.setCity(city);

				
				fullAddress = (List<Map<?, ?>>) map.get("fullAddress");

				// 回访PlusN次:field 138887
				Object adressH = map.get("138887");
				
				if (null == adressH) {
					// 首访PlusN次:field 137805
					adressH = map.get("137805");
					
					if (null == adressH) {
						// 调用【首访地址】field 93495
						addressReal = map.get("93495");
					} else {
						// 调用【首访+拜访人地址】field 137823
						addressReal = map.get("137823");
					}
				} else {
					// 调用【回访+拜访人地址】field 137821
					addressReal = map.get("137821");
				}
				
//				if (null != fullAddress) {
//
//					address = fullAddress.get(0);
//
//					String locationAddress = address.get("locationAddress").toString();
//					String adressValue = address.get("address").toString();
//
//					if (!"".equals(locationAddress)) {
//						vo.setCompanyAddress(adressValue);
//					} else {
//						vo.setCompanyAddress(locationAddress);
//					}
//					vo.setLongitude((Double) address.get("longitude"));
//
//					vo.setLatitude((Double) address.get("latitude"));
//				}

				if (null == addressReal) {
					continue;
				}
				
				vo.setCompanyAddress(addressReal.toString());

				vo.setAbandonedPerson((String) map.get(NAME_OF_ABANDONED_PERSON));

				vo.setSalesId((Long) map.get("salesId"));

				opsForHash.put(RedisConstant.COMPANY_INFO, id + "", vo);

			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return data;
	}

	private SearchColumn getSearchColumn() {

		HashOperations<String, String, SearchColumn> opsForHash = this.redisTemplate.opsForHash();

		SearchColumn searchColumn = opsForHash.get(RedisConstant.SEARCH_CITY_COLUMN, RedisConstant.SEARCH_HASH_CITY);

		if (null != searchColumn) {
			return searchColumn;
		}

		ParameterizedTypeReference<ExploringHorsesResponse<List<SearchColumn>>> parameterizedTypeReference = new ParameterizedTypeReference<ExploringHorsesResponse<List<SearchColumn>>>() {
		};

		ExploringHorsesResponse<List<SearchColumn>> exploringHorsesResponse = this.httpRequest
				.postProfileFields(parameterizedTypeReference);

		if (0 != exploringHorsesResponse.getCode()) {
			return null;
		}

		List<SearchColumn> data = exploringHorsesResponse.getData();

		// 城市 搜索条件
		SearchColumn cityColumn = data.get(3);

		opsForHash.put(RedisConstant.SEARCH_CITY_COLUMN, RedisConstant.SEARCH_HASH_CITY, cityColumn);

		//
		return searchColumn;
	}

	/**
	 * 获取组织架构
	 */
	public List<DepartmentFlatten> getOrganizeData() {

		String key = RedisConstant.getOrganizeKey();

		ListOperations<String, DepartmentFlatten> listOperations = (ListOperations<String, DepartmentFlatten>) redisTemplate
				.opsForList();

		List<DepartmentFlatten> range = listOperations.range(key, 0, listOperations.size(key));

		if (null != range && 0 != range.size()) {

			return range;
		}

		List<DepartmentFlatten> erdaoList = pushOriginByTanma(key, listOperations);

		return erdaoList;
	}

	/**
	 * 写入缓存
	 * 
	 * @param key
	 * @param listOperations
	 * @return
	 */
	private List<DepartmentFlatten> pushOriginByTanma(String key,
			ListOperations<String, DepartmentFlatten> listOperations) {
		ParameterizedTypeReference<ExploringHorsesResponse<List<Department>>> parameterizedTypeReference = new ParameterizedTypeReference<ExploringHorsesResponse<List<Department>>>() {
		};

		IOrganizeRequestParam organizeRequestParam = new OrganizeRequestParam();
		ExploringHorsesResponse<List<Department>> exploringHorsesResponse = this.httpRequest
				.geOrganize(organizeRequestParam, parameterizedTypeReference);

		if (0 != exploringHorsesResponse.getCode()) {
			return null;
		}

		List<Department> subordinateDepartments = exploringHorsesResponse.getData().get(0).getChildren();

		// 电销部 ---- 284653
		Department electricSalesDepartment = null;

		// 二道 ---- 398478
		Department erdao = null;

		for (Department department : subordinateDepartments) {

			if (284653 == department.getId()) {
				// 电销部

				electricSalesDepartment = department;
			}
			//
			if (216651 == department.getId()) {

				erdao = department.getChildren().get(1);
			}
		}

		List<DepartmentFlatten> erdaoList = FlattenTree.flattenTree(erdao, DepartmentFlatten.class);

		List<DepartmentFlatten> electricSalesDepartmentList = FlattenTree.flattenTree(electricSalesDepartment,
				DepartmentFlatten.class);

		for (DepartmentFlatten item : electricSalesDepartmentList) {
			listOperations.rightPush(key, item);
		}

		for (DepartmentFlatten item : erdaoList) {
			listOperations.rightPush(RedisConstant.DESIGNATED_NEGOTIATOR, item);
		}
		return erdaoList;
	}
}
